/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Service;

import Constants.Fishing_Command;
import Constants.PIConstants;
import Constants.Service;
import DataManager.DbManager;
import DataManager.MySQLCommonDataProvider;
import Shared.GameMapObj;
import Shared.ItemObj;
import Shared.MapManager;
import Utility.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.mina.core.session.IoSession;
import Message.Message;
import Message.SerializerHelper;
import java.util.ArrayList;

/**
 *
 * @author HaNH
 * Need These files:
 * 1.Constants.Fishing_Command;
 * 2.Can phai co   public static final int FISH_CATCHING_SERVICE= 42; trong Service.java
 */
public class FishingService {

    public static Logger log = LoggerFactory.getLogger(ParadiseService.class.getName());
    public static Logger logChat = LoggerFactory.getLogger("ChatLog");
    public static Logger logGame = LoggerFactory.getLogger("GameLog");

    public FishingService() {
        log.info("Fishing initialized");

    }

    public void processCommand(IoSession session, int userID, String userName, Message clientMsg) {

        int actionCommand = clientMsg.getActionCommand();
        switch (actionCommand) {

            case Fishing_Command.FSH_REQUEST_ENTER_SLOT:
                enterSlot(session, clientMsg, userID);
                break;

            case Fishing_Command.FSH_REQUEST_FISH_CATCH_UP:
                catchup(session, clientMsg, userID);
                break;
            case Fishing_Command.FSH_REQUEST_ROLL_FISHING_ROD:
                rollFishingRod(session, clientMsg, userID);
                break;
            case Fishing_Command.FSH_REQUEST_THROWS_FISHING_ROD:
                throwFishingRod(session, clientMsg, userID);
                break;
            case Fishing_Command.FSH_REQUEST_LEAVE_SLOT:
                exitSlot(session, clientMsg, userID);
                break;
            case Fishing_Command.FSH_REQUEST_UPDATE_SLOT:
                requestSlotInfo(session, clientMsg, userID);
                break;
            case Fishing_Command.FSH_REQUEST_ENTER_FISHING_MAP:
                requestEnterFishingMap(session, clientMsg, userID);
                break;
        }
    }

    // HaNH
    private void enterSlot(IoSession session, Message clientMsg, int userId) {
        int SlotID = SerializerHelper.readInt(clientMsg);

        String username = (String) session.getAttribute("user");
        int curMapID = (Integer) session.getAttribute("map");
        MySQLCommonDataProvider commonDataProvider = DbManager.GetCommonDataManager();
        CharacterObj charObj = commonDataProvider.loadCharacterData(userId);
        GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);


        if (!gt.checkSlotValid(SlotID, userId)) {
            Message msg = new Message(Fishing_Command.FSH_RESPONSE_ENTER_SLOT_FAIL, Service.FISHING_SERVICE);
            session.write(msg);
        } else { // Success

            Message msg = new Message(Fishing_Command.FSH_RESPONSE_ENTER_SLOT_SUCCESS, Service.FISHING_SERVICE);
            SerializerHelper.writeBoolean(PIConstants.FSH_RESPONSE_IS_TO_CLIENT, msg);

            session.write(msg);

            /*
             * BroadCast to usser
             */

            msg = new Message(Fishing_Command.FSH_RESPONSE_ENTER_SLOT_SUCCESS, Service.FISHING_SERVICE);
            SerializerHelper.writeBoolean(PIConstants.FSH_RESPONSE_IS_TO_ANOTHER_CLIENT, msg);
            SerializerHelper.writeInt(SlotID, msg);
            SerializerHelper.writeInt(userId, msg);
            ServerService.broadcastMap(curMapID, msg, username);

        }
    }

    /*
     * Check Ticket base on MapID
     * 20102 -> 20000 =>Khu sinh Thai
     * 002 =>  Khu Chinh
     * 102=>Khu cau ca Ro
     * 203=> Khu Cau Ca Loc
     * 302=> Khu cau ca Map
     */
    /*
     *Server Receive and Forward Broadcast: QuangCau, Can Cau, Cau Trung, Cau Trat, Leave Slot
     */
    private void exitSlot(IoSession session, Message clientMsg, int userid) {
        String userName = (String) session.getAttribute("user");
        int curMapID = CommonUtils.getInt(session.getAttribute("map"));

        GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);
        int slotID = gt.getSlotId(userid);
        Message msg = new Message(Fishing_Command.FSH_RESPONSE_LEAVE_SLOT, Service.FISHING_SERVICE);
        SerializerHelper.writeInt(slotID, msg);
        ServerService.broadcastMap(curMapID, msg, userName);
        gt.leaveslot(userid);

    }

    private void requestSlotInfo(IoSession session, Message clientMsg, int userid) {

        int curMapID = CommonUtils.getInt(session.getAttribute("map"));
        GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);
        byte[] SlotStatus = gt.getSlotsStatus();
        Message msg = new Message(Fishing_Command.FSH_RESPONSE_UPDATE_SLOT, Service.FISHING_SERVICE);
        SerializerHelper.writeInt(SlotStatus.length, msg);
        for (int i = 0; i < SlotStatus.length; i++) {
            SerializerHelper.writeByte(SlotStatus[i], msg);
        }
        session.write(msg);
    }

    private void requestEnterFishingMap(IoSession session, Message clientMsg, int userID) {
        MySQLCommonDataProvider commonDataProvider = DbManager.GetCommonDataManager();
        int curMapID = SerializerHelper.readInt(clientMsg);
        byte map = 0;
        if (curMapID / 100 == PIConstants.VALUE_MAP_CARO) {
            map = PIConstants.BYTE_MAP_CARO;
        } else if (curMapID / 100 == PIConstants.VALUE_MAP_CALOC) {
            map = PIConstants.BYTE_MAP_CALOC;
        } else if (curMapID / 100 == PIConstants.VALUE_MAP_CAMAP) {
            map = PIConstants.BYTE_MAP_CAMAP;
        }

        if (map == 0) {
            return;
        }

        ArrayList ticket = commonDataProvider.getFishingItems(userID, map, PIConstants.ITEM_CATEGORY_FISHING_TICKET);
        Message msg = null;
        if (ticket.isEmpty()) {
            msg = new Message(Fishing_Command.FSH_RESPONSE_ENTER_FISHING_MAP, Service.FISHING_SERVICE);
            SerializerHelper.writeBoolean(false, msg);
        } else {
            ArrayList rods = commonDataProvider.getFishingItems(userID, map, PIConstants.ITEM_CATEGORY_ROD);
            ArrayList baits = commonDataProvider.getFishingItems(userID, map, PIConstants.ITEM_CATEGORY_BAIT);
            msg = new Message(Fishing_Command.FSH_RESPONSE_ENTER_FISHING_MAP, Service.FISHING_SERVICE);
            SerializerHelper.writeBoolean(true, msg);
            SerializerHelper.writeInt(baits.size(), msg);
            SerializerHelper.writeInt(rods.size(), msg);
            int i = 0;
            for (i = 0; i < baits.size(); i++) {
                ItemObj bait = (ItemObj) baits.get(i);
                SerializerHelper.writeInt(bait.id, msg);
                SerializerHelper.writeString(bait.name, msg);
                SerializerHelper.writeInt(bait.usages, msg);
                SerializerHelper.writeInt(bait.timecatch, msg);
            }

            for (i = 0; i < rods.size(); i++) {
                ItemObj rod = (ItemObj) rods.get(i);
                SerializerHelper.writeInt(rod.id, msg);
                SerializerHelper.writeString(rod.name, msg);
            }

        }

        session.write(msg);

    }

    private void catchup(IoSession session, Message clientMsg, int userID) {
        int curMapID = CommonUtils.getInt(session.getAttribute("map"));
        String userName = (String) session.getAttribute("user");
        GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);
        int slotid = gt.getSlotId(userID);
        Message msg = new Message(Fishing_Command.FSH_RESPONSE_FISH_CATCH_UP, Service.FISHING_SERVICE);
        SerializerHelper.writeInt(slotid, msg);
        ServerService.broadcastMap(curMapID, msg, userName);
    }

    private void throwFishingRod(IoSession session, Message clientMsg, int userID) {
        int curMapID = CommonUtils.getInt(session.getAttribute("map"));
        String userName = (String) session.getAttribute("user");
        int bait = SerializerHelper.readInt(clientMsg);
        byte map = 0;
        if (curMapID / 100 == PIConstants.VALUE_MAP_CARO) {
            map = PIConstants.BYTE_MAP_CARO;
        } else if (curMapID / 100 == PIConstants.VALUE_MAP_CALOC) {
            map = PIConstants.BYTE_MAP_CALOC;
        } else if (curMapID / 100 == PIConstants.VALUE_MAP_CAMAP) {
            map = PIConstants.BYTE_MAP_CAMAP;
        }

        if (map != 0) {
            GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);
            int slotid = gt.getSlotId(userID);
            MySQLCommonDataProvider commonDataProvider = DbManager.GetCommonDataManager();
//            if (commonDataProvider.useFishingBait(userID, map, bait)) { // Use Bait Successfull
//                Message msg = new Message(Fishing_Command.FSH_RESPONSE_THROWS_FISHING_ROD, Service.FISHING_SERVICE);
//                SerializerHelper.writeBoolean(PIConstants.FSH_RESPONSE_IS_TO_CLIENT, msg);
//                SerializerHelper.writeBoolean(true, msg);
//                session.write(msg);
//
//                /*
//                 * Broadcast
//                 */
//                msg = new Message(Fishing_Command.FSH_RESPONSE_THROWS_FISHING_ROD, Service.FISHING_SERVICE);
//                SerializerHelper.writeBoolean(PIConstants.FSH_RESPONSE_IS_TO_ANOTHER_CLIENT, msg);
//                SerializerHelper.writeInt(slotid, msg);
//                ServerService.broadcastMap(curMapID, msg, userName);
//            } else {
//                Message msg = new Message(Fishing_Command.FSH_RESPONSE_THROWS_FISHING_ROD, Service.FISHING_SERVICE);
//                SerializerHelper.writeBoolean(PIConstants.FSH_RESPONSE_IS_TO_CLIENT, msg);
//                SerializerHelper.writeBoolean(false, msg);
//            }

            boolean result = commonDataProvider.useFishingBait(userID, map, bait);
            Message msg = new Message(Fishing_Command.FSH_RESPONSE_THROWS_FISHING_ROD, Service.FISHING_SERVICE);
            SerializerHelper.writeBoolean(result, msg);
            if (result) {
                SerializerHelper.writeInt(slotid, msg);
                ServerService.broadcastMap(curMapID, msg, userName);
            }
            session.write(msg);
        }
    }

    private void rollFishingRod(IoSession session, Message clientMsg, int userID) {
        int curMapID = CommonUtils.getInt(session.getAttribute("map"));
        String userName = (String) session.getAttribute("user");
        GameMapObj gt = (GameMapObj) MapManager.getInstance().getMap(curMapID);
        int slotid = gt.getSlotId(userID);
        byte fishstatus = SerializerHelper.readByte(clientMsg);

        Message msg = new Message(Fishing_Command.FSH_RESPONSE_ROLL_FISHING_ROD, Service.FISHING_SERVICE);
        SerializerHelper.writeInt(slotid, msg);
        SerializerHelper.writeByte(fishstatus, msg);
        ServerService.broadcastMap(curMapID, msg, userName);

        if (fishstatus == 1) {
            MySQLCommonDataProvider commonDataProvider = DbManager.GetCommonDataManager();
            byte map = 0;
            if (curMapID / 100 == PIConstants.VALUE_MAP_CARO) {
                map = PIConstants.BYTE_MAP_CARO;
            } else if (curMapID / 100 == PIConstants.VALUE_MAP_CALOC) {
                map = PIConstants.BYTE_MAP_CALOC;
            } else if (curMapID / 100 == PIConstants.VALUE_MAP_CAMAP) {
                map = PIConstants.BYTE_MAP_CAMAP;
            }
            if (map != 0) {
                int itemid = commonDataProvider.getFishID(map);
                if (itemid != 0) {
                    int unusedItemNo = commonDataProvider.getUserUnusedItem(userID);
                    if (unusedItemNo < PIConstants.MAX_ITEM_UNUSED) {
                        commonDataProvider.addUserInventory(userID, itemid, PIConstants.ITEM_STATUS_UNUSED);
                    }else{
                        msg = new Message(Fishing_Command.FSH_ANNOUNCE_FULL_INVENTORY, Service.FISHING_SERVICE);
                        session.write(msg);
                    }
                }
            }
        }
    }
}
